﻿using AutoMapper;
using DFGK.IRepository;
using DFGK.IService;
using DFGK_WMS.Common;
using DFGK_WMS.Model.Dto;
using DFGK_WMS.Model.Dto.YS;
using DFGK_WMS.Model.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using NPOI.SS.Formula.Functions;
using Org.BouncyCastle.Crypto;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.Metrics;
using System.Linq;
using System.Reflection.Emit;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Yitter.IdGenerator;

namespace DFGK.Service
{
    public class ReceivingBillService : BaseService, IReceivingBillService
    {
        private readonly IMaterialRepository _materialRepository;
        private readonly ICachePortRepository _cachePortRepository;
        private readonly IPackageDetailRepository _packageDetailRepository;
        private readonly IMaterialPackageReceivingRepository _packageReceivingRepository;
        private readonly IPackRepository _packRepository;
        private readonly ISupplierRepository _supplierRepository;
        private readonly ICustomerRepository _customerRepository;
        private readonly IOtherTypeRepository otherTypeRepository;
        private readonly IWarehouseRepository _warehouseRepository;
        private readonly IInventoryRepository _inventoryRepository;
        private readonly IReceivingBillRepository _receiptBillRepository;
        private readonly IMaterialPackageReceivingRepository _materialPackageReceivingRepository;
        private readonly IMaterialPackageRepository _materialPackageRepository;
        private readonly IReceivingBillDetailRepository _receiptDetailRepository;
        private readonly IUnitOfWork _unitOfWork;
        public ReceivingBillService(IMapper mapper, ISupplierRepository _supplierRepository, ICustomerRepository customerRepository, IWarehouseRepository warehouseRepository, IReceivingBillRepository receiptBillRepository, IReceivingBillDetailRepository receiptDetailRepository, IInventoryRepository _inventoryRepository, IMaterialRepository materialRepository, IUnitOfWork unitOfWork, IMaterialPackageRepository _materialPackageRepository, ICachePortRepository cachePortRepository, IPackRepository packRepository, IPackageDetailRepository packageDetailRepository, IMaterialPackageReceivingRepository materialPackageReceivingRepository, IMaterialPackageReceivingRepository packageReceivingRepository, IOtherTypeRepository otherTypeRepository) : base(mapper)
        {
            this._materialPackageRepository = _materialPackageRepository;
            this._inventoryRepository = _inventoryRepository;
            this._supplierRepository = _supplierRepository;
            _materialRepository = materialRepository;
            _customerRepository = customerRepository;
            _warehouseRepository = warehouseRepository;
            _receiptBillRepository = receiptBillRepository;
            _receiptDetailRepository = receiptDetailRepository;
            _unitOfWork = unitOfWork;
            _cachePortRepository = cachePortRepository;
            _packRepository = packRepository;
            _packageDetailRepository = packageDetailRepository;
            _materialPackageReceivingRepository = materialPackageReceivingRepository;
            _packageReceivingRepository = packageReceivingRepository;
            this.otherTypeRepository = otherTypeRepository;
        }
        /// <summary>
        /// 打包过程
        /// </summary>
        public bool AddPackageDetails(ReceivingBillAndPackage m, out string message)
        {
            ReceivingBill receivingBill = new ReceivingBill();
            receivingBill.Id=YitIdHelper.NextId();
            message = "";
            int totalQty = 0;
            // 基础数据判断赋值
            if (m.SupplierId != null)
            {
                var sobj = _supplierRepository.QueryEntityById((long)m.SupplierId);
                if (sobj != null)
                {
                    receivingBill.SupplierName = sobj.Name;
                }
               
            }
            if (m.CustomerId != null)
            {
                var cobj = _customerRepository.QueryEntityById((long)m.CustomerId);
                if (cobj != null)
                {
                    receivingBill.CustomerName = cobj.Name;
                }
              
            }
            if (m.WarehouseId != null)
            {
                var wobj = _warehouseRepository.QueryEntityById((long)m.WarehouseId);
                if (wobj != null && wobj.Status == 1)
                {
                    receivingBill.WarehouseId = wobj.Id;
                    receivingBill.WarehouseCode = wobj.Code;
                    receivingBill.WarehouseName = wobj.Name;
                }
                else
                {
                    message = "库房不存在或者已被禁用！";
                    return false;
                }
            }
            receivingBill.Status = 0;
            receivingBill.ReceivedQTY = 0;
            receivingBill.TotalQty = 0;
            receivingBill.BillNo = m.BillNo;
             receivingBill.SupplierId = m.SupplierId;
            receivingBill.Receiver = m.Receiver;
            receivingBill.OtherTypeCode = m.OtherTypeCode;
            receivingBill.TotalPrice = m.TotalPrice;
            receivingBill.WorkShopCode = m.WorkShopCode;
            receivingBill.WorkShopName = m.WorkShopName;
            receivingBill.POMode = m.POMode;
            receivingBill.BeginDate = m.BeginDate;
            receivingBill.BillType = m.BillType;
            receivingBill.StockCode = m.StockCode;
            receivingBill.StockName = m.StockName;

            _unitOfWork.BeginTransaction();
            try
            {
                _receiptBillRepository.AddEntity(receivingBill);
                _unitOfWork.SaveChangesEntity();
                // 提前查询所有物料信息
                var materialIds = m.packDtos.Select(b => b.Id).Distinct().ToList();
                var materials = _materialRepository.GetAllEntityList()
                    .Where(d => materialIds.Contains(d.Id)).ToList();
                if (materials.Count <1)
                {
                    message = "物料信息有误！";
                    _unitOfWork.RollbackChanges();
                    return false;
                }

                // 包裹处理
                //var sortedPackDtos = m.packDtos.OrderBy(x => x.PackNo).ToList();
                var sortedPackDtos = m.packDtos.ToList();
                // 遍历每个物料生成 BillDetail
                foreach (var mobj in materials)
                {
                    // 根据物料创建 BillDetail
                    var item = new ReceivingBillDetail
                    {
                        Id = YitIdHelper.NextId(),
                        MaterialId = mobj.Id,
                        MaterialName = mobj.Name,
                        MaterialCode = mobj.Code,
                        BatchNo = m.BatchNo,
                        BatchNoExplain = m.BatchNo,
                        ISPass = m.IsNeedQc.HasValue ? (m.IsNeedQc.Value ? "Y" : "N") : null,
                        MaterialTypeName = mobj.MaterialCategoryName,
                        SupplierId = m.SupplierId,
                        SupplierName = m.SupplierName,
                        ExpireDate = mobj.ExpirationMonth != null
                            ? DateTime.Now.AddMonths((int)mobj.ExpirationMonth)
                            : (DateTime?)null,
                        BillNo = m.BillNo,
                        BillId = receivingBill.Id,
                        Status = 0 // 初始化状态
                    };
                    // 包裹号处理
                    //var packageDict = new Dictionary<int, string>();
                    //string datePrefix = DateTime.Now.ToString("yyyyMMdd");
                    //int currentNumber = 0;
                    int detailQty = 0;
                    var counter = 0;
                    foreach (var item1 in sortedPackDtos)
                    {
                        if (item1.PackQty <= 0)
                        {
                            message = "包裹数量必须大于0！";
                            _unitOfWork.RollbackChanges();
                            return false;
                        }
                        counter++;
                        var packageDetail = new PackageDetail
                        {
                            Id = YitIdHelper.NextId(),
                            PackageCode = $"{counter:D4}",
                            OrderSn = m.BillNo,
                            MaterialId = item.MaterialId,
                            MaterialName = item.MaterialName,
                            MaterialCode = item.MaterialCode,
                            BatchNO = m.BatchNo,
                            UnitId = mobj.UnitId,
                            Status = 0, // 初始状态
                            UnitName = mobj.UnitName,
                            QTY = item1.PackQty,
                            RelatedOrderDetailId = receivingBill.Id, // 根据业务调整 此处为billId
                            CreateDate = DateTime.Now
                        };
                        detailQty += item1.PackQty;
                        _packageDetailRepository.AddEntity(packageDetail);
                    }
                    // 更新BillDetail和ReceivingBill
                    item.Qty = detailQty;
                    _receiptDetailRepository.AddEntity(item);
                    totalQty += detailQty; // 累加到总数量
                    _unitOfWork.SaveChangesEntity();


                    var materialPackReceiving = _materialPackageReceivingRepository.QueryEntityWhere(d => d.BillNo == m.BillNo && d.MaterialId==mobj.Id && d.BatchNo==m.BatchNo && d.Receiver==m.Receiver);

                    // 检查物料总单是否存在
                    if (materialPackReceiving == null)
                    {
                        message = "关联的物料总单不存在！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }

                    // 检查数量是否超额
                    if (materialPackReceiving.AllQty < totalQty)
                    {
                        message = "数量超额！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    // 更新物料总单的数量
                    materialPackReceiving.AllQty -= totalQty;

                    // 设置状态并更新物料总单
                    materialPackReceiving.PakcRevevingStatus = materialPackReceiving.AllQty == 0 ? 2 : 1;
                    _materialPackageReceivingRepository.UpdEntity(materialPackReceiving);
                   
                }
                // 所有数据处理完成后，更新ReceivingBill
                receivingBill.TotalQty = totalQty;
                _receiptBillRepository.UpdEntity(receivingBill);
               

              
                // 最后一次保存
                if (_unitOfWork.SaveChangesEntity())
                {
                    _unitOfWork.CommitChanges();
                    return true;
                }
                _unitOfWork.RollbackChanges();
                return false;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }
        }



        /// <summary>
        /// 打包过程显示
        /// </summary>
        /// <param name="ordersn"></param>
        /// <param name="status"></param>
        /// <param name="billtype"></param>
        /// <param name="startdate"></param>
        /// <param name="enddate"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="totalCount"></param>
        /// <returns></returns>
        //public List<ShowPackageDetailsDTO> ShowPackageDetailsList(string? ordersn, int? status, int billtype, DateTime startdate, DateTime enddate, int pageIndex, int pageSize, out int totalCount)
        //{
        //    List<ShowPackageDetailsDTO> showPackageDetails = new List<ShowPackageDetailsDTO>();

        //    var list = _packageDetailRepository.GetEntityAlls();
        //    var getReceivBillType = _receiptBillRepository.GetEntityWhereAll(d => d.BillType == billtype);
        //    var packReceivingDetailId = list.Select(d => d.RelatedOrderDetailId).ToList();
        //    var getReceivDetailList = _receiptDetailRepository.GetEntityWhereAll(d => packReceivingDetailId.Contains(d.BillId)).Select(d => d.Id);


        //    if (billtype != 0)
        //    {
        //        list = (IQueryable<PackageDetail>)list.Where(d => getReceivDetailList.Contains(d.RelatedOrderDetailId)).ToList();
        //    }

        //    // 根据状态过滤
        //    if (status < 4)
        //        list = list.Where(x => x.Status == status);
        //    if (status == 5)
        //        list = list.Where(x => x.Status < 2);

        //    // 根据订单号过滤
        //    if (!string.IsNullOrEmpty(ordersn))
        //        list = list.Where(x => x.OrderSn.Contains(ordersn));
        //    // 根据日期范围过滤
        //    if (startdate != DateTime.MinValue && enddate != DateTime.MinValue)
        //        list = list.Where(x => x.CreateDate >= startdate && x.CreateDate < enddate.AddDays(1));
        //    else if (startdate != DateTime.MinValue)
        //        list = list.Where(x => x.CreateDate >= startdate);
        //    else if (enddate != DateTime.MinValue)
        //        list = list.Where(x => x.CreateDate < enddate.AddDays(1));
        //    var lists = list.ToList();
        //    var groupedOrders = lists.GroupBy(x => x.OrderSn );
        //    foreach (var item in groupedOrders)
        //    {
        //        var getBillType = _receiptBillRepository.GetEntityWhereAll(d => d.BillNo == item.Key).Select(d => d.BillType).FirstOrDefault();
        //        ShowPackageDetailsDTO detailsDTO = new ShowPackageDetailsDTO
        //        {
        //            Id = _receiptBillRepository.GetEntityWhereAll(d => d.BillNo == item.Key).Select(d => d.Id).FirstOrDefault(),
        //            OrderSn = item.Key,
        //            CheckedAll = false,
        //            BillType = (int)getBillType,
        //            packageDetails = new List<PackageDetail>()

        //        };
        //        var plist = list.Where(x => x.OrderSn == item.Key).ToList();
        //        // 如果没有找到相关记录，跳过
        //        if (!plist.Any())
        //            continue;
        //        // 获取该订单的包裹详情
        //        detailsDTO.packageDetails = plist;
        //        // 获取状态
        //        detailsDTO.Status = GetStatus(plist.FirstOrDefault()?.Status);

        //        // 添加到最终结果
        //        showPackageDetails.Add(detailsDTO);
        //    }

        //    // 计算总条数
        //    totalCount = showPackageDetails.Count;

        //    // 分页
        //    showPackageDetails = showPackageDetails.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();

        //    return showPackageDetails;
        //}
        //public List<ShowPackageDetailsDTO> ShowPackageDetailsList(string? ordersn, int? status, int pageIndex, int pageSize, out int totalCount)
        //{
        //    List<ShowPackageDetailsDTO> showPackageDetails = new List<ShowPackageDetailsDTO>();

        //    var list = _packageDetailRepository.GetEntityAlls();
        //    var packReceivingDetailId = list.Select(d => d.RelatedOrderDetailId).ToList();
        //    var getReceivDetailList = _receiptDetailRepository.GetEntityWhereAll(d => packReceivingDetailId.Contains(d.BillId)).Select(d => d.Id);

        //    // 状态和订单号过滤逻辑保持不变
        //    if (status < 4)
        //        list = list.Where(x => x.Status == status);
        //    if (status == 5)
        //        list = list.Where(x => x.Status < 2);
        //    if (!string.IsNullOrEmpty(ordersn))
        //        list = list.Where(x => x.OrderSn.Contains(ordersn));

        //    var lists = list.ToList();
        //    var groupedOrders = lists.GroupBy(x => x.RelatedOrderDetailId).ToList();

        //    foreach (var item in groupedOrders)
        //    {
        //        // 一次查询获取 ReceivingBill 的所有相关字段（包括 CreateDate）
        //        var receiptBill = _receiptBillRepository.GetEntityWhereAll(d => d.BillNo == item.FirstOrDefault().OrderSn).FirstOrDefault();
        //        if (receiptBill == null) continue; // 如果无关联的 ReceivingBill，跳过

        //        var warecode = receiptBill.WarehouseCode;
        //        if (warecode == "K02") continue; // 跳过特定仓库

        //        // 其他字段处理
        //        var othertypecode = receiptBill.OtherTypeCode;
        //        var typename = othertypecode == null
        //            ? "无"
        //            : otherTypeRepository.QueryEntityWhere(d => d.TypeCode == othertypecode)?.TypeName ?? "无";

        //        // 创建 DTO 并添加 CreateDate
        //        ShowPackageDetailsDTO detailsDTO = new ShowPackageDetailsDTO
        //        {
        //            Id = item.Key,
        //            OrderSn = item.FirstOrDefault()?.OrderSn,
        //            CheckedAll = false,
        //            POModel = receiptBill.POMode,
        //            Status= GetStatus(item.FirstOrDefault()?.Status),
        //            OtherTypeName = typename,
        //            BillType = (int)receiptBill.BillType,
        //            CreateDate = receiptBill.CreateDate, // 新增字段
        //            packageDetails = new List<PackageDetail>()
        //        };

        //        var plist = list.Where(x => x.RelatedOrderDetailId == item.Key)
        //                       .OrderByDescending(d => d.CreateDate)
        //                       .ToList();

        //        if (!plist.Any()) continue;

        //        detailsDTO.packageDetails = plist;


        //        showPackageDetails.Add(detailsDTO);
        //    }

        //    // 按 ReceivingBill 的 CreateDate 倒序排序
        //    showPackageDetails = showPackageDetails.OrderByDescending(d => d.CreateDate).ToList();

        //    totalCount = showPackageDetails.Count;
        //    showPackageDetails = showPackageDetails.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();

        //    return showPackageDetails;
        //}

        public List<ShowPackageDetailsDTO> ShowPackageDetailsList(
    string? ordersn,
   
    int? status,
    int pageIndex,
    int pageSize,
    out int totalCount)
        {
            var result = new List<ShowPackageDetailsDTO>();

            // 1. 主表查询：从 ReceivingBill 开始，应用过滤条件
            var receivingBillsQuery = _receiptBillRepository.GetEntityAlls();

            // 按订单号过滤
            if (!string.IsNullOrEmpty(ordersn))
            {
                receivingBillsQuery = receivingBillsQuery.Where(b => b.BillNo.Contains(ordersn));
            }
          
            // 按状态过滤
            if (status.HasValue)
            {
                receivingBillsQuery = receivingBillsQuery.Where(b => b.Status == status);
            }

            // 排除特定仓库（如 K02）
            receivingBillsQuery = receivingBillsQuery.Where(b => b.WarehouseCode != "K02");
            // 排除特定仓库（如 K02）
            receivingBillsQuery = receivingBillsQuery.Where(b => !b.BillNo.Contains("DP"));
            // 2. 分页和排序：在数据库层面完成
            var pagedBills = receivingBillsQuery
                .OrderByDescending(b => b.CreateDate)
                .Skip((pageIndex - 1) * pageSize)
                .Take(pageSize)
                .ToList();

            totalCount = receivingBillsQuery.Count(); // 获取总数量

            // 3. 批量预加载所有关联的 PackageDetail
            var billIds = pagedBills.Select(b => b.Id).ToList();  // 获取所有 BillId
            var packageDetails = _packageDetailRepository
                .GetEntityWhereAll(d => billIds.Contains(d.RelatedOrderDetailId)) // 根据 RelatedOrderDetailId 过滤数据
                .ToList() // 将数据加载到内存
                .GroupBy(d => d.RelatedOrderDetailId) // 在内存中按 RelatedOrderDetailId 分组
                .ToDictionary(g => g.Key, g => g.ToList()); // 转换为字典，以便根据 RelatedOrderDetailId 快速查找

            // 4. 构建 DTO
            foreach (var bill in pagedBills)
            {
                var typename = bill.OtherTypeCode == null
                    ? "无"
                    : otherTypeRepository.QueryEntityWhere(d => d.TypeCode == bill.OtherTypeCode)?.TypeName ?? "无";

                var detailsDTO = new ShowPackageDetailsDTO
                {
                    Id = bill.Id,
                    OrderSn = bill.BillNo,
                    CheckedAll = false,
                    POModel = bill.POMode,
                    Status = GetStatus(bill.Status),
                    OtherTypeName = typename,
                    BillType = (int)bill.BillType,
                    CreateDate = bill.CreateDate,
                    // 使用 bill.Id 作为 key 来从 packageDetails 字典中获取相关的 PackageDetail 列表
                    packageDetails = packageDetails.TryGetValue(bill.Id, out var details)
                        ? details.OrderByDescending(d => d.CreateDate).ToList()
                        : new List<PackageDetail>() // 若无明细，返回空列表
                };


                result.Add(detailsDTO);
            }

            return result;
        }


        //根据收货单id获取收货单信息
        public PackageDeatilListDto?  PackageDetailByDetailId(long id,out string message)
        {
            message=string.Empty;
            var packdetail = _packageDetailRepository.GetEntityWhereAll(d => d.RelatedOrderDetailId == id).ToList();
            if (packdetail==null)
            {
                message = "找不到该单号";
                return null;
            }
            var packdetailFirst = packdetail.FirstOrDefault();
           var rece= _receiptBillRepository.QueryEntityWhere(d => d.Id == id);
            PackageDeatilListDto listDto=new PackageDeatilListDto();
            listDto.Id = rece.Id;
            listDto.Ordersn = packdetailFirst.OrderSn;
            listDto.Status = GetStatus(packdetailFirst.Status);
            listDto.StockCode = rece.StockCode;
            listDto.StockName = rece.StockName;
            listDto.packageDetails = packdetail;
            return listDto;
        }


        public bool AddReceivingBill(ReceivingBill m, out string message)
        {
            message = "";
            #region 基础数据判断赋值
            if (m.SupplierId != null)
            {
                var sobj = _supplierRepository.QueryEntityById((long)m.SupplierId);
                if (sobj != null)
                {
                    m.SupplierName = sobj.Name;
                }
                else
                {
                    message = "供应商不存在或者已被禁用！";
                    return false;
                }
            }
            if (m.CustomerId != null)
            {
                var cobj = _customerRepository.QueryEntityById((long)m.CustomerId);
                if (cobj != null)
                {
                    m.CustomerName = cobj.Name;
                }
                else
                {
                    message = "客户不存在或者已被禁用！";
                    return false;
                }
            }
            if (m.WarehouseId != null)
            {
                var wobj = _warehouseRepository.QueryEntityById((long)m.WarehouseId);
                if (wobj != null && wobj.Status == 1)
                {
                    m.WarehouseCode = wobj.Code;
                    m.WarehouseName = wobj.Name;
                }
                else
                {
                    message = "库房不存在或者已被禁用！";
                    return false;
                }
            }
            m.Status = 0;
            m.ReceivedQTY = 0;
            #endregion
            _unitOfWork.BeginTransaction();
            try
            {
                foreach (var item in m.BillDetailList)
                {
                    if (item.ProductDate != null && item.ExpireDate != null)
                    {
                        if (item.ExpireDate < item.ProductDate)
                        {
                            message = "有效日期不能小于生产日期！";
                            return false;
                        }
                    }
                    if (m.BillType == 6)
                        item.Qty = 0;
                    m.TotalQty = item.Qty;
                    _receiptBillRepository.AddEntity(m);
                    _unitOfWork.SaveChangesEntity();
                    var mobj = _materialRepository.QueryEntityById(item.MaterialId);
                    if (mobj == null)
                    {
                        message = "物料信息有误！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (item.Qty <= 0 && m.BillType != 6)
                    {
                        message = "收货数量不能小于0";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (item.Qty % 1 != 0)
                    {
                        message = "收货数量包含小数";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    item.Id = YitIdHelper.NextId();
                    item.MaterialName = mobj.Name;
                    item.MaterialCode = mobj.Code;
                    item.MaterialTypeName = mobj.MaterialCategoryName;
                    item.SupplierId = m.SupplierId;
                    item.SupplierName = m.SupplierName;
                    if (mobj.ExpirationMonth != null)
                        item.ExpireDate = DateTime.Now.AddMonths((int)mobj.ExpirationMonth);
                    //关联单号
                    item.BillNo = m.BillNo;
                    item.BillId = m.Id;
                    //初始化状态
                    item.Status = 0;
                    _receiptDetailRepository.AddEntity(item);
                }
                if (_unitOfWork.SaveChangesEntity())
                {
                    _unitOfWork.CommitChanges();
                    return true;
                }
                _unitOfWork.RollbackChanges();
                return false;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }
        }




        public bool DelReceivingBill(long rid, out string message)
        {
            message = "";
            var robj = _receiptBillRepository.QueryEntityById(rid);
            if (robj != null)
            {
                if (robj.Status == 1 || robj.Status == 2 || robj.Status == 3)
                {
                    message = "作业中和已完成的单据不能再删除";
                    return false;
                }
                _receiptBillRepository.DelEntity(robj);
                var rodobj = _receiptDetailRepository.QueryEntityWhere(x => x.BillId == robj.Id);
                if (rodobj != null)
                    _receiptDetailRepository.DelEntity(rodobj);
                return _unitOfWork.SaveChangesEntity();
            }
            message = "找不到收货单!";
            return false;
        }
        /// <summary>
        /// 删除打包的收货单
        /// </summary>
        /// <param name="rid"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool DelReceivingBillAndPakcage(long rid, out string message)
        {
            message = "";
            int totalQuantity = 0;

            // 查找收货单
            var receiptBill = _receiptBillRepository.QueryEntityWhere(d => d.Id==rid);
            if (receiptBill == null)
            {
                message = "找不到收货单!";
                return false;
            }

            // 状态判断，不能删除作业中、已完成或其他不允许删除的状态
            if (receiptBill.Status == 1 || receiptBill.Status == 2 || receiptBill.Status == 3)
            {
                message = "作业中和已完成的单据不能再删除";
                return false;
            }

            // 删除收货单及相关的明细
            _receiptBillRepository.DelEntity(receiptBill);

            // 删除收货单明细
            var receiptDetailList = _receiptDetailRepository.QueryEntityWhere(x => x.BillId == receiptBill.Id);
            if (receiptDetailList != null)
            {
                _receiptDetailRepository.DelEntity(receiptDetailList);
            }

            // 删除包裹信息
            var packageList = _packageDetailRepository.GetEntityWhereAll(d => d.RelatedOrderDetailId == receiptBill.Id).ToList();
            if (packageList.Any())
            {
                // 获取包裹的总数量
                totalQuantity = (int)packageList.Sum(pkg => pkg.QTY); // 假设包裹对象有一个 QTY 属性
                _packageDetailRepository.DelEntityList(packageList);  
            }
            else
            {
                message = "未找到对应的包裹，删除失败";
                return false;
            }

            // 保存更改
            return _unitOfWork.SaveChangesEntity();
        }
        public ReceivingBill? GetReceivingBillById(long rid)
        {
            var robj = _receiptBillRepository.QueryEntityById(rid);
            if (robj == null)
                return null;
            ReceivingBill? robjs = new ReceivingBill();
            robjs = robj;
            var rdobj = _receiptDetailRepository.QueryIsEntityWhere(x => x.BillId == robj.Id);
            if (rdobj != null)
            {
                robjs.BillDetailList.Add(rdobj);
            }
            return robj;
        }
        //public List<ReceivingBillListDto> GetReceivingBillList(string? ordersn, string? materialkey, int status, int pageIndex, int pageSize, out int totalCount)
        //{
        //    var rlist = _receiptBillRepository.GetEntityAlls().Where(d => d.WarehouseCode == "K02");
        //    var rdlist = _receiptDetailRepository.GetEntityAlls();
        //    if (!string.IsNullOrEmpty(ordersn))
        //        rlist = rlist.Where(x => x.BillNo.Contains(ordersn));

        //    if (status < 4)
        //        rlist = rlist.Where(x => x.Status == status);
        //    if (status == 5)
        //        rlist = rlist.Where(x => x.Status < 2);
        //    if (!string.IsNullOrEmpty(materialkey))
        //        rdlist = rdlist.Where(x => x.MaterialCode.Contains(materialkey) || x.MaterialName.Contains(materialkey));

        //    var list = from a in rlist
        //               join b in rdlist
        //               on a.Id equals b.BillId
        //               select new ReceivingBillListDto
        //               {
        //                   Id = a.Id,
        //                   BillNo = a.BillNo,
        //                   BillType = a.BillType,
        //                   SupplierId = a.SupplierId,
        //                   SupplierName = a.SupplierName,
        //                   Status = GetStatus(a.Status),
        //                   WorkShopCode = a.WorkShopCode,
        //                   WorkShopName = a.WorkShopName,
        //                   BeginDate = a.BeginDate,
        //                   EndDate = a.EndDate,
        //                   StockCode = a.StockCode,

        //                   OtherTypeName = string.IsNullOrEmpty(a.OtherTypeCode)
        //        ? "无"
        //        : otherTypeRepository.QueryEntityWhere(d => d.TypeCode == a.OtherTypeCode) != null
        //            ? otherTypeRepository.QueryEntityWhere(d => d.TypeCode == a.OtherTypeCode).TypeName
        //            : "无",
        //                   WarehouseCode = a.WarehouseCode,
        //                   CreateDate = a.CreateDate,
        //                   TotalQty = a.TotalQty,
        //                   POModel = a.POMode,
        //                   ReceivedQTY = b.ReceivedQty,
        //                   MaterialCode = b.MaterialCode,
        //                   MaterialName = b.MaterialName,
        //                   BatchNo = b.BatchNo,
        //               };
        //    totalCount = list.Count();
        //    var query = list.OrderByDescending(x => x.CreateDate).Skip((pageIndex - 1) * pageSize).Take(pageSize);
        //    return query.ToList();
        //}
        public List<ReceivingBillListDto> GetReceivingBillList(string? ordersn, string? materialkey, int status, int pageIndex, int pageSize, out int totalCount)
        {
            // 1. 获取基础数据并立即执行
            var rlist = _receiptBillRepository.GetEntityAlls()
                .Where(d => d.WarehouseCode == "K02")
                .ToList(); // 立即执行

            var rdlist = _receiptDetailRepository.GetEntityAlls()
                .ToList(); // 立即执行

            // 2. 应用过滤条件
            if (!string.IsNullOrEmpty(ordersn))
                rlist = rlist.Where(x => x.BillNo.Contains(ordersn)).ToList();

            if (status < 4)
                rlist = rlist.Where(x => x.Status == status).ToList();
            if (status == 5)
                rlist = rlist.Where(x => x.Status < 2).ToList();
            if (!string.IsNullOrEmpty(materialkey))
                rdlist = rdlist.Where(x => x.MaterialCode.Contains(materialkey) || x.MaterialName.Contains(materialkey)||x.ModelSpec.Contains(materialkey)).ToList();

            // 3. 执行连接操作
            var query = from a in rlist
                        join b in rdlist on a.Id equals b.BillId
                        select new
                        {
                            a.Id,
                            a.BillNo,
                            a.BillType,
                            a.SupplierId,
                            a.SupplierName,
                            Status = GetStatus(a.Status),
                            a.WorkShopCode,
                            a.WorkShopName,
                            a.BeginDate,
                            a.EndDate,
                            a.StockCode,
                            a.WarehouseCode,
                            a.CreateDate,
                            a.TotalQty,
                            a.POMode,
                            b.ReceivedQty,
                            b.MaterialCode,
                            b.ModelSpec,
                            b.MaterialName,
                            b.BatchNo,
                            OtherTypeCode = a.OtherTypeCode
                        };

            var queryResult = query.ToList(); // 强制立即执行

            // 4. 预先加载 OtherType 数据
            var otherTypeCodes = queryResult
                .Where(x => !string.IsNullOrEmpty(x.OtherTypeCode))
                .Select(x => x.OtherTypeCode)
                .Distinct()
                .ToList();

            var otherTypes = otherTypeRepository.GetEntityWhereAll(d => otherTypeCodes.Contains(d.TypeCode))
                .ToDictionary(d => d.TypeCode, d => d.TypeName);

            // 5. 分页逻辑
            totalCount = queryResult.Count;
            var pagedData = queryResult
                .OrderByDescending(x => x.CreateDate)
                .Skip((pageIndex - 1) * pageSize)
                .Take(pageSize)
                .ToList();

            // 6. 转换为 DTO
            var result = pagedData.Select(item => new ReceivingBillListDto
            {
                Id = item.Id,
                BillNo = item.BillNo,
                BillType = item.BillType,
                SupplierId = item.SupplierId,
                SupplierName = item.SupplierName,
                Status = item.Status,
                WorkShopCode = item.WorkShopCode,
                WorkShopName = item.WorkShopName,
                BeginDate = item.BeginDate,
                EndDate = item.EndDate,
                StockCode = item.StockCode,
                OtherTypeName = string.IsNullOrEmpty(item.OtherTypeCode)
                    ? "无"
                    : otherTypes.TryGetValue(item.OtherTypeCode, out var name) ? name : "无",
                WarehouseCode = item.WarehouseCode,
                CreateDate = item.CreateDate,
                TotalQty = item.TotalQty,
                POModel = item.POMode,
                ReceivedQTY = item.ReceivedQty,
                MaterialCode = item.MaterialCode,
                MaterialName = item.MaterialName,
                ModelSpec=item.ModelSpec,
                BatchNo = item.BatchNo
            }).ToList();

            return result;
        }

        private static string GetStatus(int? status)
        {
            switch (status)
            {
                case 0:
                    return "未开始";
                case 1:
                    return "未完成";
                case 2:
                    return "已完成";
            }
            return "";
        }

        public bool UpdReceivingBill(ReceivingBill m, out string message)
        {
            message = "";
            #region 基础数据判断赋值
            if (m.Status != 0)
            {
                message = "收货中和已完成单据不可修改！";
                return false;
            }
            if (m.SupplierId != null)
            {
                var sobj = _supplierRepository.QueryEntityById((long)m.SupplierId);
                if (sobj != null)
                {
                    m.SupplierName = sobj.Name;
                }
                else
                {
                    message = "供应商不存在或者已被禁用！";
                    return false;
                }
            }
            if (m.CustomerId != null)
            {
                var cobj = _customerRepository.QueryEntityById((long)m.CustomerId);
                if (cobj != null)
                {
                    m.CustomerName = cobj.Name;
                }
                else
                {
                    message = "客户不存在或者已被禁用！";
                    return false;
                }
            }
            if (m.WarehouseId != null)
            {
                var wobj = _warehouseRepository.QueryEntityById((long)m.WarehouseId);
                if (wobj != null && wobj.Status == 1)
                {
                    m.WarehouseCode = wobj.Code;
                    m.WarehouseName = wobj.Name;
                }
                else
                {
                    message = "库房不存在或者已被禁用！";
                    return false;
                }
            }
         
            #endregion
            _unitOfWork.BeginTransaction();
            try
            {
            
                var rdlist = _receiptDetailRepository.GetEntityWhereAll(x => x.BillId == m.Id);
                if (rdlist.Any())
                    _receiptDetailRepository.DelEntityList(rdlist.ToList());
                foreach (var item in m.BillDetailList)
                {
                    if (item.ProductDate != null && item.ExpireDate != null)
                    {
                        if (item.ExpireDate < item.ProductDate)
                        {
                            message = "有效日期不能小于生产日期！";
                            return false;
                        }
                    }
                    if (m.BillType == 6)
                        item.Qty = 0;
                    m.TotalQty = item.Qty;
                    _receiptBillRepository.UpdEntity(m);
                    var mobj = _materialRepository.QueryEntityById(item.MaterialId);
                    if (mobj == null)
                    {
                        message = "物料信息有误！";
                        return false;
                    }
                    if (item.Qty <= 0 && m.BillType != 6)
                    {
                        message = "收货数量不能小于0";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (item.Qty % 1 != 0)
                    {
                        message = "收货数量包含小数";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    item.Id = YitIdHelper.NextId();
                    item.MaterialName = mobj.Name;
                    item.MaterialCode = mobj.Code;
                    item.MaterialTypeName = mobj.MaterialCategoryName;
                    item.SupplierId = m.SupplierId;
                    item.SupplierName = m.SupplierName;
                    //关联单号
                    item.BillNo = m.BillNo;
                    item.BillId = m.Id;
                    _receiptDetailRepository.AddEntity(item);
                }
                if (_unitOfWork.SaveChangesEntity())
                {
                    _unitOfWork.CommitChanges();
                    return true;
                }
                _unitOfWork.RollbackChanges();
                return false;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }
        }

        public ReceivingBillListDto? GetReceivingBillByMaerialCode(string code, long aid, out string message)
        {
            message = string.Empty;
            var redobj = _receiptDetailRepository.QueryIsEntityWhere(x => x.MaterialCode == code && x.Status == 0);
            if (redobj == null)
            {
                message = "找不到该物料！";
                return null;
            }
            var reobj = _receiptBillRepository.QueryEntityById(redobj.BillId);
            if (reobj == null)
            {
                message = "找不到收货单明细！";
                return null;
            }
            var materpackobj = _materialPackageRepository.QueryEntityWhere(x => x.MaterialId == redobj.MaterialId);
            ReceivingBillListDto select = new ReceivingBillListDto();
            select.Id = reobj.Id;
            select.BillNo = reobj.BillNo;
            select.SupplierId = reobj.SupplierId;
            select.SupplierName = reobj.SupplierName;
            select.Status = GetStatus(reobj.Status);
            select.BeginDate = reobj.BeginDate;
            select.EndDate = reobj.EndDate;
            select.CreateDate = reobj.CreateDate;
            select.TotalQty = reobj.TotalQty;
            select.ReceivedQTY = redobj.ReceivedQty;
            select.MaterialCode = redobj.MaterialCode;
            select.MaterialName = redobj.MaterialName;
            select.BatchNo = redobj.BatchNo;

            var ilist = _inventoryRepository.GetEntityWhereAll(x => (x.MaterialCode == code || x.MaterialName == "空料箱") && x.Status == 1 && x.IsLock == false && x.BatchNo == redobj.BatchNo && x.AreaId == aid);
            if (ilist.Any())
            {
                message = "库存中已有该批次物料！";
                select.inventories = ilist.ToList();
                return select;
            }

            return select;
        }

        public ReceivingBillListDto? GetReceivingBillByDetailId(long id, out string message)
        {
            message = string.Empty;
            var reobj = _receiptBillRepository.QueryEntityById(id);

            if (reobj == null)
            {
                message = "找不到收货单！";
                return null;
            }

            var redobj = _receiptDetailRepository.QueryEntityWhere(x => x.BillId == id);
            if (redobj == null)
            {
                message = "找不到收货单明细！";
                return null;
            }

            decimal? sqty = 0;
            decimal? zqty = 0;
            decimal? wsqty = 0;
            decimal? wzqty = 0;
            ReceivingBillListDto select = new ReceivingBillListDto();
            select.Id = reobj.Id;
            select.BillNo = reobj.BillNo;
            select.SupplierId = reobj.SupplierId;
            select.SupplierName = reobj.SupplierName;
            select.Status = GetStatus(reobj.Status);
            select.BeginDate = reobj.BeginDate;
            select.EndDate = reobj.EndDate;
            select.CreateDate = reobj.CreateDate;
            select.TotalQty = reobj.TotalQty;
            select.ReceivedQTY = redobj.ReceivedQty;
            select.MaterialCode = redobj.MaterialCode;
            select.MaterialName = redobj.MaterialName;
            select.BatchNo = redobj.BatchNo;
            if (Config.IsReplenishment == true)
            {
                var materpackobj = _materialPackageRepository.QueryEntityWhere(x => x.MaterialId == redobj.MaterialId);
                if (materpackobj != null)
                {
                    sqty = select.TotalQty % materpackobj.ConversionFactor;
                    zqty = (select.TotalQty - sqty) / materpackobj.ConversionFactor;
                    wsqty = (select.TotalQty - select.ReceivedQTY) % materpackobj.ConversionFactor;
                    wzqty = (select.TotalQty - select.ReceivedQTY - wsqty) / materpackobj.ConversionFactor;
                    select.SQty = "散件：" + (int?)sqty + " " + materpackobj.SubPackageUnitName;
                    select.ZQty = "整件：" + (int?)zqty + " " + materpackobj.PackageUnitName;
                    select.WSQty = "散件：" + (int?)wsqty + " " + materpackobj.SubPackageUnitName;
                    select.WZQty = "整件：" + (int?)wzqty + " " + materpackobj.PackageUnitName;
                }
                else
                {
                    var materobj = _materialRepository.QueryEntityById(redobj.MaterialId);
                    select.SQty = "散件：0";
                    select.WSQty = "散件：0";
                    if (materobj != null)
                    {
                        select.ZQty = "整件：" + (int?)select.TotalQty + "" + materobj.UnitName;
                        select.WZQty = "整件：" + (int?)(select.TotalQty - select.ReceivedQTY) + "" + materobj.UnitName;
                    }
                    else
                    {
                        select.ZQty = "整件：" + (int?)select.TotalQty;
                        select.WZQty = "整件：" + (int?)(select.TotalQty - select.ReceivedQTY);
                    }
                }
            }
            else
            {
                var materobj = _materialRepository.QueryEntityById(redobj.MaterialId);
                if (materobj != null)
                {
                    select.ZQty = "";
                    select.WZQty = "";
                    select.SQty = (int?)reobj.TotalQty + " " + materobj.UnitName;
                    select.WSQty = (int?)(reobj.TotalQty - redobj.ReceivedQty) + " " + materobj.UnitName;
                }
                else
                {
                    select.ZQty = "";
                    select.WZQty = "";
                    select.SQty = (int?)reobj.TotalQty + "";
                    select.WSQty = (int?)(reobj.TotalQty - redobj.ReceivedQty) + "";
                }
            }

            var ilist = _inventoryRepository.GetEntityWhereAll(x => (x.MaterialCode == redobj.MaterialCode && x.Status == 1 && x.IsLock == false && x.BatchNo == redobj.BatchNo && x.AreaCode.Contains("L")) || (x.MaterialName == "空料箱" && x.Status == 1 && x.IsLock == false && x.AreaCode.Contains("L")));

            if (ilist.Any())
            {
                message = "库存中已有该批次物料！";
                select.inventories = ilist.OrderBy(x => x.AvailableQty).ToList();
                return select;
            }

            return select;
        }

      
    }
}
